package com.googlecode.connectlet.crypto.digest;

import java.io.OutputStream;
import java.io.Serializable;

import com.googlecode.connectlet.util.Base64;
import com.googlecode.connectlet.util.Bytes;

public abstract class DigestStream extends OutputStream implements Serializable {
	private static final long serialVersionUID = 1L;

	@Override
	public abstract void write(byte[] b, int off, int len);
	public abstract void reset();
	public abstract byte[] digest();

	@Override
	public void write(int b) {
		write(new byte[] {(byte) b});
	}

	@Override
	public void write(byte[] b) {
		write(b, 0, b.length);
	}

	@Override
	public void flush() {/**/}

	@Override
	public void close() {/**/}

	public String digestBase64() {
		return Base64.encode(digest());
	}

	public String digestHexUpper() {
		return Bytes.toHexUpper(digest());
	}

	public String digestHexLower() {
		return Bytes.toHexLower(digest());
	}

	public byte[] digest(byte[] b) {
		return digest(b, 0, b.length);
	}

	public byte[] digest(byte[] b, int off, int len) {
		write(b, off, len);
		byte[] result = digest();
		reset();
		return result;
	}

	public String digestBase64(byte[] b) {
		return digestBase64(b, 0, b.length);
	}

	public String digestBase64(byte[] b, int off, int len) {
		return Base64.encode(digest(b, off, len));
	}

	public String digestHexUpper(byte[] b) {
		return digestHexUpper(b, 0, b.length);
	}

	public String digestHexUpper(byte[] b, int off, int len) {
		return Bytes.toHexUpper(digest(b, off, len));
	}

	public String digestHexLower(byte[] b) {
		return digestHexLower(b, 0, b.length);
	}

	public String digestHexLower(byte[] b, int off, int len) {
		return Bytes.toHexLower(digest(b, off, len));
	}
}